package com.block.product.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.block.common.annotate.RedisLock;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.service.IChannelCommonService;
import com.block.common.service.LogFactory;
import com.block.common.vo.ResponseVo;
import com.block.db.entity.*;
import com.block.db.mapper.MemberBaseInfoMapper;
import com.block.db.mapper.ProductUnionResultInfoMapper;
import com.block.merchant.enums.FlowRateTypeEnum;
import com.block.product.enums.UniStatusEnum;
import com.block.product.factory.UnionLoginFactory;
import com.block.product.model.dto.UniLoginDTO;
import com.block.product.model.param.ProdApiInfoParam;
import com.block.product.model.result.UnionLoginResult;
import com.block.product.model.vo.UnionProdResultVO;
import com.block.product.service.*;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * <p>
 * 产品联登结果信息 服务实现类
 * </p>
 *
 * @author 
 * @since 2023-12-10
 */
@Service
public class ProductUnionResultInfoServiceImpl extends ServiceImpl<ProductUnionResultInfoMapper, ProductUnionResultInfo> implements IProductUnionResultInfoService {

    private static final Logger log = LogFactory.getProductLog();

    @Autowired
    IProductBaseInfoService productBaseInfoService;
    @Autowired
    IProductUnionLoginService productUnionLoginService;

    @Resource
    ProductUnionResultInfoMapper productUnionResultInfoMapper;
    @Resource
    MemberBaseInfoMapper memberBaseInfoMapper;
    @Autowired
    NotifyExceptionService notifyExceptionService;
    @Autowired
    IProductDataUnionCountInfoService productDataUnionCountInfoService;
    @Autowired
    IChannelCommonService channelCommonService;

    @Override
    @RedisLock(lockName = "PROD::UNION::LOGIN", key = "#redisKey" )
    public ResponseVo getProdUnionResult(String productId, Long uid, String redisKey, ChannelBaseInfo channelBaseInfo) {

        ProductBaseInfo productBaseInfo = productBaseInfoService.getProductInfoById(Integer.valueOf(productId));

        UnionProdResultVO prodResultVO = new UnionProdResultVO();
        prodResultVO.setSuccess(false);
        prodResultVO.setProductId(String.valueOf(productBaseInfo.getId()));
        prodResultVO.setProductName(productBaseInfo.getProductName());

        ProductUnionResultInfo unionResultInfo = this.baseMapper.getEntityByProductIdAndUid(productId, uid);
        if (ObjectUtil.isEmpty(unionResultInfo)){
            prodResultVO.setSuccess(false);
            prodResultVO.setMessage("联登记录为空");
            return new ResponseVo(AppRspCodeConstant.SUCCESS, prodResultVO);
        }

        if (StrUtil.equals(unionResultInfo.getStatus(), UniStatusEnum.SUCCESS.getValue())){
            LocalDateTime expireTime = unionResultInfo.getExpireTime();
            LocalDateTime nowTime = LocalDateTime.now();
            if (nowTime.plusDays(2).isBefore(expireTime)){
                prodResultVO.setSuccess(true);
                prodResultVO.setDetailUrl(unionResultInfo.getLoginUrl());
            }else{
                prodResultVO.setSuccess(false);
                prodResultVO.setMessage("展示时间超时");
            }
            return new ResponseVo(AppRspCodeConstant.SUCCESS, prodResultVO);
        }

        if (StrUtil.equals(unionResultInfo.getStatus(), UniStatusEnum.WAIT_LOGIN.getValue())){
            // 需要进行联登操作
            ProductUnionResultInfo loginResult = productUnionLoginService.getUnionProductLoginResult(unionResultInfo.getId(), uid, unionResultInfo.getProductId(),channelBaseInfo);
            log.info("【产品联登点击】联登结果【infoId】{}【productId】{}【loginResult】{}", unionResultInfo.getId(), productBaseInfo.getId(), JSON.toJSONString(loginResult));
            if (ObjectUtil.isNotEmpty(loginResult) && StrUtil.equals(loginResult.getStatus(), UniStatusEnum.SUCCESS.getValue())){
                prodResultVO.setSuccess(true);
                prodResultVO.setDetailUrl(loginResult.getLoginUrl());
            }else{
                prodResultVO.setSuccess(false);
                prodResultVO.setMessage("联登失败");
            }
            return new ResponseVo(AppRspCodeConstant.SUCCESS, prodResultVO);
        }

        log.info("【产品联登点击】状态错误，不进行处理【productId】{}【uid】{}", productBaseInfo.getId(), uid);

        prodResultVO.setSuccess(false);
        prodResultVO.setMessage("联登状态不支持："+ unionResultInfo.getStatus());
        return new ResponseVo(AppRspCodeConstant.SUCCESS, prodResultVO);
    }


    @Override
    @RedisLock(lockName = "PROD::UNION::CHECK", key = "#redisKey" )
    public ProductUnionResultInfo getUnionProductCheckResult(ProductBaseInfo productBaseInfo, Long uid, String redisKey,ChannelBaseInfo channelBaseInfo) {
        try {
            MemberBaseInfo memberBaseInfo = memberBaseInfoMapper.selectById(uid);

            ProductUnionResultInfo productUnionResultInfo = new ProductUnionResultInfo();
            productUnionResultInfo.setProductId(productBaseInfo.getId());
            productUnionResultInfo.setProductName(productBaseInfo.getProductName());
            productUnionResultInfo.setDateInfo(LocalDate.now().toString());
            productUnionResultInfo.setUid(uid);
            productUnionResultInfo.setMobile(memberBaseInfo.getMobile());
            productUnionResultInfo.setStatus(UniStatusEnum.INIT.getValue());
            productUnionResultInfo.setChannelCode(memberBaseInfo.getChannelCode());
            productUnionResultInfo.setChannelName(memberBaseInfo.getChannelName());

            productUnionResultInfoMapper.insert(productUnionResultInfo);

            // 进行撞库操作
            ProductDataUnionCountInfo productDataUnionCountInfo = new ProductDataUnionCountInfo();
            productDataUnionCountInfo.setProductId(productBaseInfo.getId());
            productDataUnionCountInfo.setProductName(productBaseInfo.getProductName());
            productDataUnionCountInfo.setDateInfo(LocalDate.now().toString());
            productDataUnionCountInfo.setCheckNumber(1);
//            ChannelBaseInfo channelBaseInfo = channelCommonService.getBaseInfoByCode(memberBaseInfo.getChannelCode());
            if(StrUtil.equals(channelBaseInfo.getFlowRateType(), FlowRateTypeEnum.H5.getValue())){
                productDataUnionCountInfo.setCheckNumberH5(1);
            }
            if(StrUtil.equals(channelBaseInfo.getFlowRateType(), FlowRateTypeEnum.WX.getValue())){
                productDataUnionCountInfo.setCheckNumberMini(1);
            }
            if(StrUtil.equals(channelBaseInfo.getFlowRateType(), FlowRateTypeEnum.APP.getValue())){
                productDataUnionCountInfo.setCheckNumberApp(1);
            }

            UniLoginDTO uniLoginDTO = new UniLoginDTO();
            uniLoginDTO.setMobile(memberBaseInfo.getMobile());

            ProdApiInfoParam prodApiInfoParam = this.getProdApiInfoParam(productBaseInfo);

            UnionLoginResult checkResult = UnionLoginFactory.getService(productBaseInfo.getFactoryType()).checkUser(uniLoginDTO, prodApiInfoParam);
            log.info("【产品联登撞库】撞库操作【checkResult】{}【UniLoginDTO】{}【productId】{}", JSON.toJSONString(checkResult), JSON.toJSONString(uniLoginDTO), productBaseInfo.getId());

            ProductUnionResultInfo updateEntity = new ProductUnionResultInfo();
            updateEntity.setId(productUnionResultInfo.getId());
            updateEntity.setCode(checkResult.getCode());
            updateEntity.setMessage(checkResult.getMessage());
            updateEntity.setResultInfo(checkResult.getResultInfo());
            updateEntity.setParamInfo(checkResult.getParamInfo());

            if (checkResult.isSuccess()) {
                productDataUnionCountInfo.setCheckSuccessNumber(1);
                if(StrUtil.equals(channelBaseInfo.getFlowRateType(), FlowRateTypeEnum.H5.getValue())){
                    productDataUnionCountInfo.setCheckSuccessNumberH5(1);
                }
                if(StrUtil.equals(channelBaseInfo.getFlowRateType(), FlowRateTypeEnum.WX.getValue())){
                    productDataUnionCountInfo.setCheckSuccessNumberMini(1);
                }
                if(StrUtil.equals(channelBaseInfo.getFlowRateType(), FlowRateTypeEnum.APP.getValue())){
                    productDataUnionCountInfo.setCheckSuccessNumberApp(1);
                }
                productDataUnionCountInfoService.updateDateUnionCountInfo(productDataUnionCountInfo);
                updateEntity.setStatus(UniStatusEnum.WAIT_LOGIN.getValue());
            } else {
                productDataUnionCountInfoService.updateDateUnionCountInfo(productDataUnionCountInfo);
                updateEntity.setStatus(UniStatusEnum.MATCH_FAILD.getValue());
            }
            int i = productUnionResultInfoMapper.updateById(updateEntity);
            log.info("【产品联登撞库】更新撞库结果【i】{}【uid】{}【productId】{}", 1, uid, productBaseInfo.getId());
            if (i > 0) {
                return productUnionResultInfoMapper.selectById(productUnionResultInfo.getId());
            }
        } catch (Exception exception) {
            exception.printStackTrace();
            String message = StrUtil.format("【uid】{}【productId】{}",uid, productBaseInfo.getId());
            notifyExceptionService.notifyNoticeInfo("UNION_PRODUCT_CHECk", "联登撞库异常", message, exception);
        }
        return null;
    }


    private ProdApiInfoParam getProdApiInfoParam(ProductBaseInfo productBaseInfo) {
        ProdApiInfoParam prodApiInfoParam = new ProdApiInfoParam();
        prodApiInfoParam.setApiCode(productBaseInfo.getApiCode());
        prodApiInfoParam.setApiKey(productBaseInfo.getApiKey());
        prodApiInfoParam.setApiSecret(productBaseInfo.getApiSecret());
        prodApiInfoParam.setApiPubKey(productBaseInfo.getPubKey());
        prodApiInfoParam.setApiPriKey(productBaseInfo.getPriKey());
        prodApiInfoParam.setCheckUrl(productBaseInfo.getCheckUrl());
        prodApiInfoParam.setLoginUrl(productBaseInfo.getLoginUrl());
        return prodApiInfoParam;
    }


}
